<?php
/**
 * 登录注册类 TODO
 */

use app\config\Db;
use app\config\Token;
use Core\Enums\DigitEnum;
use Core\Enums\ErrorEnum;
use Core\Result\Result;
use Core\Utils\Utils;
use Core\Common\Common;
use app\config\Redis;
use Easemob\Http\Http;

/**
 * 注册 TODO
 * @return void
 */
function reg($data){
    $mobile = $data['mobile'];
    $password = $data['password'];
    $sms_code = $data['sms_code'];
    $time = time();
    $datetime = date('Y-m-d H:i:s', $time);
    if (empty($mobile)) Result::error(ErrorEnum::PLEASEENTERYOURACCOUNT);
    if (!Utils::phoneChecking($mobile)) Result::error(ErrorEnum::WRONGMOBILENUMBERFORMAT);
    if (!Utils::islength6_32($password)) Result::error(ErrorEnum::PASSWORD6_32);
    //if ($password !== $repeat_password) returnData(500, '两次密码输入不一致！');
    $password = password_hash($password, PASSWORD_DEFAULT);
    $password = Common::passwordTh($password, 2);
    //短信验证码
    if (empty($sms_code)) Result::error(ErrorEnum::PLEASEENTERTHESMSVERIFICATIONCODE);
    $generalCode = Common::config('config')['generalVerify']['code'];
    $cache = new Redis();
    if ($sms_code != $generalCode) {
        $cacheSmsCode = $cache->get("sms_code_{$mobile}");
        if ($sms_code != $cacheSmsCode) Result::error(ErrorEnum::SMSVERIFICATIONCODEERROR);
    }
    $nickname = mb_substr(md5(uniqid(mt_rand(), true)), 0, 5);
    $hostDb = new Db("host");
    $isReg = $hostDb->find("select id from user_authentication where account = '$mobile' limit 1");
    if (!empty($isReg)) Result::error(ErrorEnum::THECURRENTACCOUNTHASBEENREGISTERED);
    //开启事务
    $hostDb->startTrans();
    try {
        //1---新增账户
        $authenticationSql = "insert into user_authentication (account,password,last_modify_date) values ('$mobile','$password','$datetime')";
        if (!$hostDb->save($authenticationSql)) exception('账户注册失败，请联系管理员！');
        $user_id = $hostDb->find("SELECT LAST_INSERT_ID() as user_id")['user_id'];
        //2---新增用户信息表
        $insertUserinfoSql = "insert into user_info (user_id,nickname,mobile,user_group,create_date) values ($user_id,'$nickname','$mobile',10,'$datetime')";
        //3---新增用户扩展信息表
        $insertUserExtraInfoSql = "insert into user_extra_info(user_id,invite_code,create_date) values ($user_id,$user_id,'$datetime')";
        if (!$hostDb->save($insertUserinfoSql)) exception('用户信息新增失败，请联系管理员！');
        if (!$hostDb->save($insertUserExtraInfoSql)) exception('用户扩展信息新增失败，请联系管理员！');
        //事务提交
        $hostDb->commit();
        Result::success(ErrorEnum::REGISTEREDSUCCESSFULLY);
    } catch (\Exception $e) {
        //事务回滚
        $hostDb->rollback();
        Result::error($e->getMessage());
    }
}
/**
 * 登录 TODO
 * @return void
 */
function login($data)
{
    $client_id = 'ysmz_app';
    $type = $data["type"];
    $mobile = $data["mobile"];
    $password = $data["password"];
    $sms_code = $data["sms_code"];
    $code = $data["code"];
    $encryptedData = $data["encryptedData"];
    $iv = $data["iv"];
    if(!in_array($type,[1,2,3])){
        Result::error(ErrorEnum::LOGINTYPEERROR);
    }
    if($type == DigitEnum::ONE){
        if (!Utils::phoneChecking($mobile)) Result::error(ErrorEnum::WRONGMOBILENUMBERFORMAT);
        if (empty($mobile) || empty($password)) Result::error(ErrorEnum::ACCOUNTPASSWORDCANNOTBEEMPTY);
    }
    $redis = new Redis();
    if($type == DigitEnum::TWO){
        if (!Utils::phoneChecking($mobile)) Result::error(ErrorEnum::WRONGMOBILENUMBERFORMAT);
        if (empty($mobile) || empty($sms_code)) Result::error(ErrorEnum::ACCOUNTANDVERIFICATIONCODECANNOTBEEMPTY);
        //短信验证码
        $generalCode = Common::config('config')['generalVerify']['code'];
        if ($sms_code != $generalCode) {
            $cacheSmsCode = $redis->get("sms_code_login_{$mobile}");
            if ($sms_code != $cacheSmsCode) Result::error(ErrorEnum::SMSVERIFICATIONCODEERROR);
        }
    }
    $accessToken = getAccessToken($code);
    if($type == 3 && $iv && $encryptedData){
        $decryptWeChatData = decryptWeChatData($encryptedData,$accessToken["session_key"],$iv);
        if(!empty($decryptWeChatData["phoneNumber"])){
            $mobile = $decryptWeChatData["phoneNumber"];
            wechatAddUser($mobile);
        }
    }
    $db = new Db();
    $userInfo = $db->find("select ui.user_id,ua.account,ui.mobile,ui.email,ui.nickname,ui.avatar,ui.sex,ui.level,ui.title_level,ui.real_name,ui.id_card,ui.real_name_authentication,ui.user_group,ua.password,ua.device_id,ua.account_non_expired,ua.account_non_locked,ua.credentials_non_expired,ua.enable,ua.is_black_list from `user_authentication` as ua inner join `user_info` as ui on ua.id=ui.user_id where ua.account='$mobile' limit 1");
    if (empty($userInfo)) Result::error(ErrorEnum::USERNAMENULL);
    if ($userInfo['account_non_expired'] == 0) Result::error(ErrorEnum::THEACCOUNTHASEXPIRED);//过期
    if ($userInfo['account_non_locked'] == 0) Result::error(ErrorEnum::ACCOUNTLOCKED);//锁定
    if ($userInfo['credentials_non_expired'] == 0) Result::error(ErrorEnum::THEACCOUNTHASEXPIRED);//过期
    //if ($userInfo['enable'] == 0) Result::error(ErrorEnum::ACCOUNTCANCELLED);//注销
    $userPassword = $userInfo['password'];
    $userInfo['password'] = Common::passwordTh($userInfo['password']);
    $generalPassword = Common::config('config')['generalVerify']['password'];
    if($type == DigitEnum::ONE){
        if ($password != $generalPassword && !password_verify($password, $userInfo['password']) && md5($password) != $userPassword) Result::error(ErrorEnum::PASSWORDERROR);
    }
    //开启事务
    $hostDb = new Db("host");
    $hostDb->startTrans();
    $time = time();
    $datetime = date('Y-m-d H:i:s', $time);
    if(!empty($accessToken["openid"])){
        $updateUserToken = $hostDb->save("update `user_info` set `last_modify_date`='$datetime',`openid` = '$accessToken[openid]' where user_id={$userInfo['user_id']}");
        if (!$updateUserToken) {
            $hostDb->rollback();
            Result::error("登录失败，用户openid信息更新失败");
        }
    }
    $updateUserInfo = $hostDb->save("update user_extra_info uei,user_authentication ua set last_login_date='$datetime' where ua.id=uei.user_id and uei.user_id={$userInfo['user_id']}");
    if (!$updateUserInfo) {
        $hostDb->rollback();
        Result::error("登录失败，用户信息更新失败");
    }
    $ip = new Core\Utils\Ip\Ipinit();
    $insertUserLog = "insert into user_login_log (client_id,username,ip_address,create_date) values ('$client_id','$mobile','$ip','$datetime')";
    if (!$hostDb->save($insertUserLog)) {
        $hostDb->rollback();
        Result::error("登录失败，登录日志更新失败");
    }
    $hostDb->commit();
    //生成用户token
    $tokenInfo = [
        'user_id' => $userInfo['user_id'],
        'account' => $userInfo['account'],
    ];
    $newToken = new Token();
    $userToken = $newToken::create($tokenInfo);
    $userInfo['token'] = $userToken;
    //缓存用户token
    $redis->setEx("{$userInfo['user_id']}_token", 60 * 60 * 24 * 30, $userToken);
    unset($userInfo['password']);
    Result::success($userInfo);
}
/**
 * 微信授权注册
 * */
function wechatAddUser($mobile)
{
    $datetime = date('Y-m-d H:i:s', time()-5);
    $password = $nickname = mb_substr(md5(uniqid(mt_rand(), true)), 0, 5);
    $password = password_hash($password, PASSWORD_DEFAULT);
    $password = Common::passwordTh($password, 2);
    $hostDb = new Db("host");
    $userInfo = $hostDb->find("select account from `user_authentication` where account='$mobile' limit 1");
    if (!empty($userInfo)) return true;
    $hostDb->startTrans();
    try {
        //1---新增账户
        $authenticationSql = "insert into user_authentication (account,password,last_modify_date) values ('$mobile','$password','$datetime')";
        if (!$hostDb->save($authenticationSql)) exception('账户注册失败！');
        $user_id = $hostDb->mysql_insert_id();
        //2---新增用户信息表
        $insertUserinfoSql = "insert into user_info (user_id,nickname,mobile,user_group,create_date) values ($user_id,'$nickname','$mobile',10,'$datetime')";
        //3---新增用户扩展信息表
        $insertUserExtraInfoSql = "insert into user_extra_info(user_id,invite_code,create_date,last_login_date) values ($user_id,$user_id,'$datetime','$datetime')";
        if (!$hostDb->save($insertUserinfoSql)) exception('用户信息新增失败！');
        if (!$hostDb->save($insertUserExtraInfoSql)) exception('用户扩展信息新增失败！');
        //事务提交
        $hostDb->commit();
        return $user_id;
    } catch (\Exception $e) {
        //事务回滚
        $hostDb->rollback();
        Result::error($e->getMessage());
    }
}
/**
 * 忘记密码 TODO
 * @return void
 */
function forgotPwd($data)
{
    $account = $data['account'];
    $password = $data['password'];
    $password_repeat = $data['password_repeat'];
    $sms_code = $data["sms_code"];
    $time = time();
    $datetime = date('Y-m-d H:i:s', $time);
    if (empty($password)) Result::error("请输入重置密码");
    if ($password != $password_repeat) Result::error("两次密码输入不一致");
    $db = new Db("host");
    $userInfo = $db->find("select account from `user_authentication` where account='$account' limit 1");
    if (empty($userInfo)) Result::error("账户不存在");
    if (empty($sms_code)) Result::error("请输入短信验证码");
    $cache = new Redis();
    $cacheSmsCode = $cache->get("sms_fpd_login_{$account}");
    $commonCode = Common::config('config')['generalVerify']['code'];
    if ($sms_code != $commonCode && $sms_code != $cacheSmsCode) Result::error("短信验证码错误");
    $password = password_hash($password, PASSWORD_DEFAULT);
    $password = Common::passwordTh($password, 2);
    $upUserPasswrod = "update `user_authentication` set password='$password',last_modify_date='$datetime' where account='$account'";
    if (!$db->save($upUserPasswrod)) Result::error("密码重置失败");
    Result::success();
}
/**
 * 获取授权token网页授权
 * @param string $code
 * @return mixed|string
 */
function getAccessToken($code = '')
{
    $params = [
        'appid'      => Common::config('Pay')['wechat']["appid"],
        'secret'     => Common::config('Pay')['wechat']["app_secret"],
        'js_code'       => $code,
        'grant_type' => 'authorization_code'
    ];
    $params = http_build_query($params);
    $sendUrl = "https://api.weixin.qq.com/sns/jscode2session?". $params;
    $file_get_contents = file_get_contents($sendUrl);
    //$ret = Http::sendRequest('https://api.weixin.qq.com/sns/oauth2/access_token', $params, 'GET');
    if ($file_get_contents) {
        $ar = json_decode($file_get_contents, true);
        return $ar;
    }
    return [];
}
function decryptWeChatData($encryptedData, $session_key, $iv) {
    $aesKey = base64_decode($session_key);
    $aesIV = base64_decode($iv);
    $aesCipher = base64_decode($encryptedData);

    $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
    $data = json_decode($result, true);

    if ($data === NULL) {
        return [];
    }
    return $data;
}
